/*
* 
* Fichier source projet intel Acceler8 sous license GNU GPL v3.
* Voir http://www.gnu.org/copyleft/gpl.html pour plus d'informations
* La license est egalement disponible dans le repertoire /doc
* 
* Cree le : jeudi 10 novembre 2011 à 15 : 17.
* Auteurs : Axel MOINET et Arnaud DURAND.
* 
* Nom de fichier : cgh.cpp
* Chemin du fichier : ./src/classes/cgh/cgh.cpp
* 
* Description : Classe d'implémentation du calcul de Cgh.
* 			Utilisé avec un thread POSIX pour lancer le calcul en parallèle de la lecture du fichier.
* 
*/

#include "cgh.h"

cgh::cgh(threadPrincipal *p_thread) {
	if(p_thread == NULL) {
		//Lancer une exception pointeur nul
	}
	else {
		this->g = 1;
		this->h = 1;
		this->thread = p_thread;
	}
}

/*
 * Lancement du calcul des Cgh en boucles parallèles (parallel_for)
 * Utilise les classes d'implémentation de la parallélisation de boucle :
 * parallelForCgh()
 */
int cgh::computeAllCgh() {

	FLAG lastCompute = false;
	FLAG continuer = true;

	while(this->thread->getPrefixeTab()->size() < 2){}

	while(continuer) {

			/*if( *(this->thread->g) == (*(this->thread->getPrefixeTab())).size() )
				return -1;*/

			//if( this->h >= (*(this->thread->getPrefixeTab())).size() && !this->thread->getEndFileFlag()) {
				//waitForData(this->thread->getPrefixeTab(), this->h, this->thread);
			//}

			if(this->h >= this->thread->getPrefixeTab()->size()  && !this->thread->getEndFileFlag() )
				waitForData(this->thread->getPrefixeTab(), this->h, this->thread);

			this->cghTab = new tbb::concurrent_vector<int>();
			this->cghTab->grow_by( (*(this->thread->getPrefixeTab()))[0].size() );

			tbb::parallel_for(tbb::blocked_range<int>(0, (*(this->thread->getPrefixeTab() ))[0].size()), parallelForCGH(this->g, this->h, this->thread, this->cghTab));
			//Lancer requete pour calcul SSUM PSUM (modification de flag et tableau de cgh)
			// !! Synchronisation d'accès au tableau pour écriture / pop (mutex)
			//Ajout du Cgh calculé au tableau de Cgh

			this->calculSousSequence = new (tbb::task::allocate_additional_child_of(*this)) subSeqCompute(*(this->cghTab), this->g, this->h, this->thread, lastCompute);
			tbb::task::spawn(*(this->calculSousSequence));

			this->h++;

			if (this->h >= (*(this->thread->getPrefixeTab())).size() && this->thread->getEndFileFlag()) {
				this->g++;
				this->h = this->g;
			}

			if( this->g == (*(this->thread->getPrefixeTab())).size() )
				continuer = false;
		}
	this->increment_ref_count();
	this->wait_for_all();
	this->thread->setCghComputeEndingFlag();
	return 0;
}

tbb::task* cgh::execute() {
	this->computeAllCgh();
	return NULL;
}
